diff --unified --recursive --new-file sash-3.7/Makefile sash-3.7-fb/Makefile
--- sash-3.7/Makefile	2002-07-22 01:24:47.000000000 +0200
+++ sash-3.7-fb/Makefile	2004-07-04 10:45:45.000000000 +0200
@@ -3,12 +3,18 @@
 #
 # The HAVE_GZIP definition adds the -gzip and -gunzip commands.
 # The HAVE_LINUX_ATTR definition adds the -chattr and -lsattr commands.
+# The HAVE_LINUX_CHROOT definition adds the -chroot command.
+# The HAVE_LINUX_PIVOT definition adds the -pivot_root command.
+# The HAVE_LINUX_LOSETUP definition adds the -losetup command.
 # The HAVE_LINUX_MOUNT definition makes -mount and -umount work on Linux.
 # The HAVE_BSD_MOUNT definition makes -mount and -umount work on BSD.
 # The MOUNT_TYPE definition sets the default file system type for -mount.
 #
 HAVE_GZIP		= 1
 HAVE_LINUX_ATTR		= 1
+HAVE_LINUX_CHROOT	= 1
+HAVE_LINUX_LOSETUP	= 1
+HAVE_LINUX_PIVOT	= 1
 HAVE_LINUX_MOUNT	= 1
 HAVE_BSD_MOUNT		= 0
 MOUNT_TYPE		= '"ext3"'
@@ -17,6 +23,9 @@
 CFLAGS = -O3 -Wall -Wmissing-prototypes \
 	-DHAVE_GZIP=$(HAVE_GZIP) \
 	-DHAVE_LINUX_ATTR=$(HAVE_LINUX_ATTR) \
+ 	-DHAVE_LINUX_CHROOT=$(HAVE_LINUX_CHROOT) \
+ 	-DHAVE_LINUX_LOSETUP=$(HAVE_LINUX_LOSETUP) \
+ 	-DHAVE_LINUX_PIVOT=$(HAVE_LINUX_PIVOT) \
 	-DHAVE_LINUX_MOUNT=$(HAVE_LINUX_MOUNT) \
 	-DHAVE_BSD_MOUNT=$(HAVE_BSD_MOUNT) \
 	-DMOUNT_TYPE=$(MOUNT_TYPE)
diff --unified --recursive --new-file sash-3.7/cmds.c sash-3.7-fb/cmds.c
--- sash-3.7/cmds.c	2002-07-22 00:28:19.000000000 +0200
+++ sash-3.7-fb/cmds.c	2004-07-04 10:45:45.000000000 +0200
@@ -21,6 +21,16 @@
 #include <linux/fs.h>
 #endif
 
+/* Need to tell loop.h what the actual dev_t type is. */
+#undef dev_t
+#if defined(__alpha) || (defined(__sparc__) && defined(__arch64__))
+#define dev_t unsigned int
+#else
+#define dev_t unsigned short
+#endif
+#include <linux/loop.h>
+#undef dev_t
+#define dev_t dev_t
 
 void
 do_echo(int argc, const char ** argv)
@@ -147,6 +157,28 @@
 }
 
 
+#if HAVE_LINUX_PIVOT
+
+void
+do_pivot_root(int argc, const char ** argv)
+{
+	if (pivot_root(argv[1], argv[2]) < 0)
+		perror("");
+}
+
+#endif
+
+#if HAVE_LINUX_CHROOT
+
+void
+do_chroot(int argc, const char ** argv)
+{
+	if (chroot(argv[1]) < 0)
+		perror("");
+}
+
+#endif
+
 void
 do_rmdir(int argc, const char ** argv)
 {
@@ -1253,4 +1285,62 @@
 		printf("Program \"%s\" not found in PATH\n", program);
 }
 
+#if HAVE_LINUX_LOSETUP
+
+void
+do_losetup(int argc, const char ** argv)
+{
+	int loopfd;
+	int targfd;
+	struct loop_info loopInfo;
+
+	if (!strcmp(argv[1], "-d")) {
+		loopfd = open(argv[2], O_RDWR);
+		if (loopfd < 0) {
+			fprintf(stderr, "Error opening %s: %s\n", argv[2], 
+				strerror(errno));
+			return;
+		}
+
+		if (ioctl(loopfd, LOOP_CLR_FD, 0)) {
+			fprintf(stderr, "Error unassociating device: %s\n", 
+				strerror(errno));
+			return;
+		}
+	}
+
+	loopfd = open(argv[1], O_RDWR);
+	if (loopfd < 0) {
+		fprintf(stderr, "Error opening %s: %s\n", argv[1], 
+			strerror(errno));
+		return;
+	}
+
+	targfd = open(argv[2], O_RDWR);
+	if (targfd < 0) {
+		fprintf(stderr, "Error opening %s: %s\n", argv[2], 
+			strerror(errno));
+		return;
+	}
+
+	if (ioctl(loopfd, LOOP_SET_FD, targfd)) {
+		fprintf(stderr, "Error setting up loopback device: %s\n", 
+			strerror(errno));
+		return;
+	}
+
+	memset(&loopInfo, 0, sizeof(loopInfo));
+	strcpy(loopInfo.lo_name, argv[2]);
+
+	if (ioctl(loopfd, LOOP_SET_STATUS, &loopInfo)) {
+		fprintf(stderr, "Error setting up loopback device: %s\n", 
+			strerror(errno));
+		return;
+	}
+
+	return;
+}
+
+#endif
+
 /* END CODE */
diff --unified --recursive --new-file sash-3.7/sash.1 sash-3.7-fb/sash.1
--- sash-3.7/sash.1	2004-01-14 06:04:50.000000000 +0100
+++ sash-3.7-fb/sash.1	2004-07-04 10:45:45.000000000 +0200
@@ -22,11 +22,11 @@
 These built-in commands are:
 .PP
 .nf
-     -ar, -chattr, -chgrp, -chmod, -chown, -cmp, -cp,
-     -dd, -echo, -ed, -grep, -file, -find, -gunzip,
-     -gzip, -kill, -ln, -ls, -lsattr, -mkdir, -mknod,
-     -more, -mount, -mv, -printenv, -pwd, -rm, -rmdir,
-     -sum, -sync, -tar, -touch, -umount, -where
+     -ar, -chattr, -chgrp, -chmod, -chown, -chroot, -cmp,
+     -cp, -dd, -echo, -ed, -grep, -file, -find, -gunzip,
+     -gzip, -kill, -losetup, -ln, -ls, -lsattr, -mkdir,
+     -mknod, -more, -mount, -mv, -pivot_root, -printenv, -pwd,
+     -rm, -rmdir, -sum, -sync, -tar, -touch, -umount, -where
 .fi
 .PP
 These commands are generally similar to the standard programs with similar
@@ -138,6 +138,13 @@
 can
 either be a user name, or a decimal value.
 .TP
+.B -chroot path
+Changes  the  root  directory to that specified in
+.I path.
+This directory
+will be used for path  names  beginning with /. The root directory is
+inherited by all children of the current process.
+.TP
 .B -cmp fileName1 fileName2
 Determines whether or not the specified file names have identical data.
 This says that the files are links to each other, are different sizes,
@@ -312,6 +319,20 @@
 QUIT, KILL, TERM, STOP, CONT, USR1 or USR2.
 If no signal is specified then SIGTERM is used.
 .TP
+.B -losetup [-d] loopDev [file]
+Associates loopback devices with files on the system. If
+.I -d
+is not given,
+the loopback device
+.I loopDev
+is associated with
+.I file.
+If
+.I -d
+is given,
+.I loopDev
+is unassociated with the file it's currently configured for.
+.TP
 .B -ln [-s] srcName ... destName
 Links one or more files from the
 .I srcName
@@ -388,6 +409,13 @@
 this fails because of the files being on different filesystems,
 then copies and deletes are done instead.
 .TP
+.B -pivot_root newRoot putOld
+Moves the root file system of the current process to the directory
+.I putOld
+and makes
+.I newRoot
+the  new root file system of the current process.
+.TP
 .B -printenv [name]
 If
 .I name
diff --unified --recursive --new-file sash-3.7/sash.c sash-3.7-fb/sash.c
--- sash-3.7/sash.c	2004-01-14 06:08:03.000000000 +0100
+++ sash-3.7-fb/sash.c	2004-07-04 10:45:45.000000000 +0200
@@ -15,7 +15,7 @@
 #include "sash.h"
 
 
-static const char * const	version = "3.7";
+static const char * const	version = "3.7-fb";
 
 
 /*
@@ -107,6 +107,14 @@
 		"srcName ... destName"
 	},
 
+#ifdef	HAVE_LINUX_CHROOT
+	{
+		"-chroot",	do_chroot,	2,	2,
+		"change root file system",
+		"new_root_dir"
+	},
+#endif
+
 	{
 		"-dd",		do_dd,		3,	INFINITE_ARGS,
 		"Copy data between two files",
@@ -181,6 +189,14 @@
 		"[-sig] pid ..."
 	},
 
+#ifdef	HAVE_LINUX_LOSETUP
+	{
+		"-losetup",	do_losetup,	3,	3,
+		"Associate a loopback device with a file",
+		"[-d] device\n       -losetup device filename"
+	},
+#endif
+
 	{
 		"-ln",		do_ln,		3,	INFINITE_ARGS,
 		"Link one fileName to another",
@@ -237,6 +253,14 @@
 		"srcName ... destName"
 	},
 
+#ifdef	HAVE_LINUX_PIVOT
+	{
+		"-pivot_root",	do_pivot_root,	3,	3,
+		"pivot the root file system",
+		"new_dir old_dir"
+	},
+#endif
+
 	{
 		"-printenv",	do_printenv,	1,	2,
 		"Print environment variables",
@@ -383,6 +407,7 @@
 static	void	showPrompt(void);
 static	void	usage(void);
 static	Alias *	findAlias(const char * name);
+static	void	expandVariable(char * name);
 
 
 /*
@@ -702,6 +727,11 @@
 	}
 
 	/*
+	 * Expand simple environment variables
+	 */
+	while (strstr(cmd, "$(")) expandVariable((char *)cmd);
+
+	/*
 	 * Now look for the command in the builtin table, and execute
 	 * the command if found.
 	 */
@@ -1275,4 +1305,29 @@
 	exit(1);
 }
 
+/*
+ * Expand one environment variable: Syntax $(VAR)
+ */
+static void
+expandVariable(char * cmd)
+{
+	char	tmp[CMD_LEN];
+	char 	*cp;
+	char	*ep;
+
+	strcpy(tmp, cmd);
+	cp = strstr(tmp, "$(");
+	if (cp) {
+		*cp++ = '\0';
+		strcpy(cmd, tmp);
+		ep = ++cp;
+		while (*ep && (*ep != ')')) ep++;
+		if (*ep == ')') *ep++ = '\0';
+		cp = getenv(cp);
+		if (cp) strcat(cmd, cp);
+		strcat(cmd, ep);
+	}
+	return;
+}
+
 /* END CODE */
diff --unified --recursive --new-file sash-3.7/sash.h sash-3.7-fb/sash.h
--- sash-3.7/sash.h	2002-07-22 00:05:17.000000000 +0200
+++ sash-3.7-fb/sash.h	2004-07-04 10:45:45.000000000 +0200
@@ -110,6 +110,18 @@
 extern	void	do_chattr(int argc, const char ** argv);
 #endif
 
+#if	HAVE_LINUX_CHROOT
+extern	void	do_chroot(int argc, const char ** argv);
+#endif
+
+#if	HAVE_LINUX_LOSETUP
+extern	void	do_losetup(int argc, const char ** argv);
+#endif
+
+#if	HAVE_LINUX_PIVOT
+extern	void	do_pivot_root(int argc, const char ** argv);
+extern  int pivot_root(const char *new_root, const char *put_old);
+#endif
 
 /*
  * Global utility routines.
